package cn.tannn.cat.file.server.service.impl;

import cn.tannn.cat.file.sdk.config.LocalConfig;
import cn.tannn.cat.file.sdk.core.OssCache;
import cn.tannn.cat.file.sdk.core.ftp.FtpUtils;
import cn.tannn.cat.file.sdk.core.minio.MinioUtils;
import cn.tannn.cat.file.sdk.core.qiniu.QiNiuUtils;
import cn.tannn.cat.file.sdk.enums.StorageDict;
import cn.tannn.cat.file.sdk.enums.StorageMaster;
import cn.tannn.cat.file.sdk.exception.FileException;
import cn.tannn.cat.file.server.dao.FileStorageConfigDao;
import cn.tannn.cat.file.server.entity.FileStorageConfig;
import cn.tannn.cat.file.server.init.LocalInitDynamicResourceHandlerManager;
import cn.tannn.cat.file.server.service.FileIndexMetaService;
import cn.tannn.cat.file.server.service.FileStorageConfigService;
import cn.tannn.cat.file.server.util.FileUtils;
import cn.tannn.jdevelops.exception.built.BusinessException;
import cn.tannn.jdevelops.jpa.service.J2ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;

import static cn.tannn.cat.file.sdk.exception.FileExceptionCodeEnums.FILE_CONFIG_MASTER_NONENTITY;


/**
 * 存储器配置
 *
 * @author <a href="https://tannn.cn/">tan</a>
 * @date 2024/3/7 14:23
 */
@Slf4j
@Service
public class FileStorageConfigServiceImpl extends J2ServiceImpl<FileStorageConfigDao, FileStorageConfig, Long> implements FileStorageConfigService {

    private final FileIndexMetaService fileIndexMetaService;
    private final LocalInitDynamicResourceHandlerManager localInitDynamicResourceHandlerManager;


    public FileStorageConfigServiceImpl(FileIndexMetaService fileIndexMetaService
            , LocalInitDynamicResourceHandlerManager localInitDynamicResourceHandlerManager) {
        super(FileStorageConfig.class);
        this.fileIndexMetaService = fileIndexMetaService;
        this.localInitDynamicResourceHandlerManager = localInitDynamicResourceHandlerManager;
    }

    @Override
    public void delete(Long id) {
        getJpaBasicsDao().findById(id)
                .ifPresent(config -> {
                    if (config.getMaster().equals(StorageMaster.MASTER)) {
                        throw new BusinessException("Master节点不允许删除");
                    }
                    if (config.toFileStorage().minioConfig()) {
                        MinioUtils.deleteMinioClient(id);
                    } else if (config.toFileStorage().qiNiuConfig()) {
                        QiNiuUtils.deleteQiNiuClient(id);
                    } else if (config.toFileStorage().ftpConfig()) {
                        FtpUtils.deleteFtpConnectInfo(id);
                    } else if (config.toFileStorage().localConfig()) {
                        LocalConfig localConfig = config.toFileStorage()
                                .getConfig().toJavaObject(LocalConfig.class);
                        FileUtils.removeResourceMapping(localConfig
                                , localInitDynamicResourceHandlerManager);
                    }
                });
        if (fileIndexMetaService.using(id)) {
            throw new BusinessException("当前配置存在文件数据，请删除文件数据后在删除此配置");
        }
        getJpaBasicsDao().deleteById(id);
    }

    @Override
    public void changeMaster(Long id) {
        // 处理当前id之外，其他的都变成 slave
        getJpaBasicsDao().changeSlave(id);
        // 设置当前id为 master
        getJpaBasicsDao().updateMaster(StorageMaster.MASTER, id);
    }

    @Override
    public FileStorageConfig findMaster() {
        return getJpaBasicsDao()
                .findMaster()
                .orElseThrow(() -> FileException.specialMessage(FILE_CONFIG_MASTER_NONENTITY));
    }

    @Override
    public List<FileStorageConfig> findLocalConfig() {
        return getJpaBasicsDao().findConfig(StorageDict.LOCAL_STORAGE.getValue());
    }

    @Override
    public List<FileStorageConfig> findMinioConfig() {
        return getJpaBasicsDao().findConfig(StorageDict.MINIO_STORAGE.getValue());
    }

    @Override
    public List<FileStorageConfig> findFtpConfig() {
        return getJpaBasicsDao().findConfig(StorageDict.FTP_STORAGE.getValue());
    }

    @Override
    public List<FileStorageConfig> findQiNiuConfig() {
        return getJpaBasicsDao().findConfig(StorageDict.QINIU_STORAGE.getValue());
    }

    @Override
    public void append(FileStorageConfig config) {
        if (exist(config.getName())) {
            throw new BusinessException("当前存储器配置名已存在请勿");
        }
        // 有id更新，无id新增
        updateData(config);
    }


    @Override
    public void updateData(FileStorageConfig config) {
        // 操作 minio client 缓存
        FileStorageConfig save = getJpaBasicsDao().save(config);
        if (save.toFileStorage().minioConfig()) {
            MinioUtils.createMinioClient(config.toFileStorage());
        } else if (save.toFileStorage().qiNiuConfig()) {
            QiNiuUtils.createQiNiuClient(config.toFileStorage());
        } else if (save.toFileStorage().ftpConfig()) {
            OssCache.ftpConnectInfoCache.put(config.getId(), config.toFileStorage());
        } else if (save.toFileStorage().localConfig()) {
            LocalConfig localConfig = config.toFileStorage().getConfig().toJavaObject(LocalConfig.class);
            // 验证目录是否存在
            if (!FileUtils.exist(localConfig.getUploadDir())) {
                return;
            }
            FileUtils.appendResourceMapping(localConfig
                    , localInitDynamicResourceHandlerManager);
        }
    }

    /**
     * 查重
     *
     * @param name 配置名
     * @return true 存在
     */
    boolean exist(String name) {
        return getJpaBasicsDao().findByName(name).isPresent();
    }
}
